#ifndef __server__h
#define __server__h

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sstream>
#include <strings.h>  
#include <map>
#include "wrk_config_loader.h"
#include "wrk_channel.h"
#include "ae.h"
#include "wrk_logger.h"
#include "protocol.h"

#define MAX_CONN 10

using namespace std;

class server
{
public:
	server();
	server(const char *path);
	~server();
	int run(const string &conf);

	static size_t sock_readable(int fd);
	
	static int wrk_read(int fd, stringstream &ss, ssize_t *readn);

	static int wrk_write(int fd, const char *buf, ssize_t total_length, ssize_t *writen);

	static pid_t wrk_spawn_process(void *data, char *name);

	static wrk::WrkLogger *logger;

	static pid_t master_pid; //用来区分主子进程

private:	

	static string push_host;
	static string push_service;
	static string push_uri;

	static int bind_fd;

	static WrkConfigLoader *cfg_ptr;

	static aeEventLoop *ae;

	// static std::string log;
	static int lock_file_fd;

	static ssize_t push_message(const char *host, const char *service, const char *push_uri, const string &str);

	static void init_daemon();

	static void init_signal();

	static void init_conf(const string &conf);

	static void init_single_instance();

	static void init_logger();

	void init_tcp_server();

	int start_tcp_server();

	int init_tcp_sock(struct sockaddr_in &sin, socklen_t &sin_len, uint32_t port, string ip);

	static void
	read_cb(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);

	static void
	write_cb(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);

	static void 
	connected_cb(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);

	static void 
	read_from_worker(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);

	static size_t sock_can_readable(int fd);
	
	static void init_socket_pair();
	
	static int init_aeEventLoop();

	void start_worker_process();

	static void response2client(int fd, stringstream &ss, ssize_t n);

	// cmd handlers
	static void master_start_task_handler(int fd, wrk_channel_t ch, void *data);

	static void master_stop_task_handler(int fd, wrk_channel_t ch, void *data);

	static void master_stats_task_handler(int fd, wrk_channel_t ch, void *data);

	static void master_upload_file_handler(int fd, wrk_channel_t ch, void *data);

	static wrk_cmd_handler_t cmd_handlers[];

};

#endif